/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// OpenGL ES 2.0 code

#include <jni.h>
#include <android/log.h>

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "matrix.h"

#define  LOG_TAG    "libgljni"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

#define POSITION_DATA_SIZE 3
#define COLOR_DATA_SIZE 4
#define NORMAL_DATA_SIZE 3

GLfloat gMVPMatrix[16] = { 0.0f };
GLfloat gViewMatrix[16] = { 0.0f };
GLfloat gModelMatrix[16] = { 0.0f };
GLfloat gProjectionMatrix[16] = { 0.0f };

GLfloat gLightModelMatrix[16] = { 0.0f };
GLfloat gLightPosInWorldSpace[4] = { 0.0f };
GLfloat gLightPosInModelSpace[4] = { 0.0f, 0.0f, 0.0f, 1.0f};
GLfloat gLightPosInEyeSpace[4] = { 0.0f };

GLuint gMVPMatrixHandle = 0;
GLuint gPositionHandle = 0;
GLuint gColorHandle = 0;
GLuint gProgram = 0;

GLuint gGridMVPMatrixHandle = 0;
GLuint gGridPositionHandle = 0;
GLuint gGridColorHandle = 0;
GLuint gGridProgram = 0;

GLuint gLightPosHandle = 0;
GLuint gNormalHandle = 0;
GLuint gMVMatrixHandle = 0;

GLfloat eyeX = 0.0f;
GLfloat eyeY = -5.0f;
GLfloat eyeZ = 0.0f;

GLfloat lookX = 0.0f;
GLfloat lookY = 0.0f;
GLfloat lookZ = -5.0f;

GLfloat upX = 0.0f;
GLfloat upY = 1.0f;
GLfloat upZ = 0.0f;

const GLfloat cubePosition[] = {
		-1.0f, 1.0f, 1.0f,
		-1.0f, -1.0f, 1.0f,
		1.0f, 1.0f, 1.0f,
		-1.0f, -1.0f, 1.0f,
		1.0f, -1.0f, 1.0f,
		1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, 1.0f,
		1.0f, -1.0f, 1.0f,
		1.0f, 1.0f, -1.0f,
		1.0f, -1.0f, 1.0f,
		1.0f, -1.0f, -1.0f,
		1.0f, 1.0f, -1.0f,
		1.0f, 1.0f, -1.0f,
		1.0f, -1.0f, -1.0f,
		-1.0f, 1.0f, -1.0f,
		1.0f, -1.0f, -1.0f,
		-1.0f, -1.0f, -1.0f,
		-1.0f, 1.0f, -1.0f,
		-1.0f, 1.0f, -1.0f,
		-1.0f, -1.0f, -1.0f,
		-1.0f, 1.0f, 1.0f,
		-1.0f, -1.0f, -1.0f,
		-1.0f, -1.0f, 1.0f,
		-1.0f, 1.0f, 1.0f,
		-1.0f, 1.0f, -1.0f,
		-1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, -1.0f,
		-1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, -1.0f,
		1.0f, -1.0f, -1.0f,
		1.0f, -1.0f, 1.0f,
		-1.0f, -1.0f, -1.0f,
		1.0f, -1.0f, 1.0f,
		-1.0f, -1.0f, 1.0f,
		-1.0f, -1.0f, -1.0f };

const GLfloat cubeColor[] = { 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
		1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
		1.0f, 0.0f, 0.0f, 1.0f,

		0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
		0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,

		0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,

		1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
		1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,

		0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
		0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,

		1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
		1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };

GLfloat normal[] = {
        // Front face
        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f,

        // Right face
        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,

        // Back face
        0.0f, 0.0f, -1.0f,
        0.0f, 0.0f, -1.0f,
        0.0f, 0.0f, -1.0f,
        0.0f, 0.0f, -1.0f,
        0.0f, 0.0f, -1.0f,
        0.0f, 0.0f, -1.0f,

        // Left face
        -1.0f, 0.0f, 0.0f,
        -1.0f, 0.0f, 0.0f,
        -1.0f, 0.0f, 0.0f,
        -1.0f, 0.0f, 0.0f,
        -1.0f, 0.0f, 0.0f,
        -1.0f, 0.0f, 0.0f,

        // Top face
        0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,

        // Bottom face
        0.0f, -1.0f, 0.0f,
        0.0f, -1.0f, 0.0f,
        0.0f, -1.0f, 0.0f,
        0.0f, -1.0f, 0.0f,
        0.0f, -1.0f, 0.0f,
        0.0f, -1.0f, 0.0f

};
GLfloat grid[] = {
		-10.0f, 0.0f, -1.0f,
		10.0f, 0.0f, -1.0f,
		0.0f, -10.0f, -1.0f,
		0.0f, 10.0f, -1.0f };

const GLfloat gridcolor[] = {
		1.0f, 1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, 1.0f, 1.0f,
		1.0f, 1.0f, 1.0f, 1.0f, };

GLfloat cylinder[] = {
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, -1.0f, 0.0f
};

const GLfloat cylindercolors[] = {
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
		0.0f, 0.0f, 1.0f, 1.0f,
};

GLfloat cylindertop[] = {
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
};

GLfloat cylindertopnormal[] = {
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
};

GLfloat cylinderbottom[] = {
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
};

GLfloat cylinderbottomnormal[] = {
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
};


static const char gVertexShader[] = {
		"uniform mat4 u_MVPMatrix;      \n"
		"uniform mat4 u_MVMatrix; 		\n"
		"uniform vec3 u_LightPos;  		\n"

		"attribute vec4 a_Position;     \n"
		"attribute vec4 a_Color;        \n"
		"attribute vec3 a_Normal;        \n"

		"varying vec4 v_Color;          \n"
		"float intensity = 10.0; 		\n"

		"void main()                    \n"
		"{                              \n"
		"	vec3 modelViewVertex = vec3(u_MVMatrix * a_Position); \n"
		" 	vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0)); \n"
		"   float distance = length(u_LightPos - modelViewVertex); \n"
		"	vec3 lightVector = normalize(u_LightPos - modelViewVertex);\n"
		"   float diffuse = max(dot(modelViewNormal, lightVector), 0.1); \n"
		"   diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance))); \n"
		"   v_Color = a_Color * diffuse * intensity; \n"
		"   gl_Position = u_MVPMatrix   \n"
		"               * a_Position;   \n"
		"}                              \n"
};

static const char gFragmentShader[] = {
		"precision mediump float;       \n"
		"varying vec4 v_Color;          \n"
		"void main()                    \n"
		"{                              \n"
		"   gl_FragColor = v_Color;     \n"
		"}                              \n"

};

static const char gGridVertexShader[] = {
		"uniform mat4 u_MVPMatrix;      \n"

		"attribute vec4 a_Position;     \n"
		"attribute vec4 a_Color;        \n"

		"varying vec4 v_Color;          \n"

		"void main()                    \n"
		"{                              \n"
		"   v_Color = a_Color; \n"
		"   gl_Position = u_MVPMatrix   \n"
		"               * a_Position;   \n"
		"}                              \n"
};

static const char gGridFragmentShader[] = {
		"precision mediump float;       \n"
		"varying vec4 v_Color;          \n"
		"void main()                    \n"
		"{                              \n"
		"   gl_FragColor = v_Color;     \n"
		"}                              \n"

};

GLuint loadShader(GLenum type, const char* source) {
	GLuint shader = glCreateShader(type);
	if (shader) {
		glShaderSource(shader, 1, &source, NULL);
		glCompileShader(shader);
		GLint compileStatus = 0;
		glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
		if (!compileStatus) {
			GLint info_length = 0;
			glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_length);
			if (info_length) {
				char* buf = (char*) malloc(info_length * sizeof(char));
				if (buf) {
					glGetShaderInfoLog(shader, info_length, NULL, buf);
					LOGE("Create shader %d failed\n%s\n", type, buf);
				}
			}
			glDeleteShader(shader);
			shader = 0;
		}
	}
	return shader;
}

GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
	GLuint vshader = loadShader(GL_VERTEX_SHADER, pVertexSource);
	if (!vshader) {
		return 0;
	}
	GLuint fshader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
	if (!fshader) {
		return 0;
	}
	GLuint program = glCreateProgram();
	if (program) {
		glAttachShader(program, vshader);
		glAttachShader(program, fshader);
		glBindAttribLocation(program, 0, "a_Position");
		glBindAttribLocation(program, 1, "a_Color");

		glLinkProgram(program);

		GLint status = 0;
		glGetProgramiv(program, GL_LINK_STATUS, &status);

		if (!status) {
			GLint info_length = 0;
			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_length);
			if (info_length) {
				char* buf = (char*) malloc(info_length * sizeof(char));
				glGetProgramInfoLog(program, info_length, NULL, buf);
				LOGE("create program failed\n%s\n", buf);
			}
			glDeleteProgram(program);
			program = 0;
		}
	}
	return program;
}

static GLfloat angleInDegrees = 0.1;

void setupGraphics() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glUseProgram(gGridProgram);
	gGridMVPMatrixHandle = glGetUniformLocation(gGridProgram, "u_MVPMatrix");
	gGridPositionHandle = glGetAttribLocation(gGridProgram, "a_Position");
	gGridColorHandle = glGetAttribLocation(gGridProgram, "a_Color");

	glUseProgram(gProgram);
	gMVPMatrixHandle = glGetUniformLocation(gProgram, "u_MVPMatrix");
	gPositionHandle = glGetAttribLocation(gProgram, "a_Position");
	gColorHandle = glGetAttribLocation(gProgram, "a_Color");
	gMVMatrixHandle  = glGetUniformLocation(gProgram, "u_MVMatrix");
	gLightPosHandle = glGetUniformLocation(gProgram, "u_LightPos");
	gNormalHandle = glGetAttribLocation(gProgram, "a_Normal");



}

void drawCube(const GLfloat* positions, const GLfloat* colors) {
	glUseProgram(gProgram);
	glVertexAttribPointer(gPositionHandle, POSITION_DATA_SIZE, GL_FLOAT,
			GL_FALSE, 0, positions);
	glEnableVertexAttribArray(gPositionHandle);
	glVertexAttribPointer(gColorHandle, COLOR_DATA_SIZE, GL_FLOAT, GL_FALSE, 0,
			colors);
	glEnableVertexAttribArray(gColorHandle);
	glVertexAttribPointer(gNormalHandle, NORMAL_DATA_SIZE, GL_FLOAT, GL_FALSE,
			0, normal);
	glEnableVertexAttribArray(gNormalHandle);

	multiplyMM(gMVPMatrix, 0, gViewMatrix, 0, gModelMatrix, 0);
	glUniformMatrix4fv(gMVMatrixHandle, 1, GL_FALSE, gMVPMatrix);

	multiplyMM(gMVPMatrix, 0, gProjectionMatrix, 0, gMVPMatrix, 0);

	glUniformMatrix4fv(gMVPMatrixHandle, 1, GL_FALSE, gMVPMatrix);

	glUniform3f(gLightPosHandle, gLightPosInEyeSpace[0], gLightPosInEyeSpace[1], gLightPosInEyeSpace[2]);

	glDrawArrays(GL_TRIANGLES, 0, 36);
}

void drawgrid() {
	glUseProgram(gGridProgram);
	for (int i = -20; i <= 20; i++) {
		grid[1] = grid[4] = (float) i * 0.5f;
		glVertexAttribPointer(gGridPositionHandle, POSITION_DATA_SIZE, GL_FLOAT,
				GL_FALSE, 0, grid);
		glEnableVertexAttribArray(gGridPositionHandle);
		glVertexAttribPointer(gGridColorHandle, COLOR_DATA_SIZE, GL_FLOAT, GL_FALSE,
				0, gridcolor);
		glEnableVertexAttribArray(gGridColorHandle);

		multiplyMM(gMVPMatrix, 0, gViewMatrix, 0, gModelMatrix, 0);
		multiplyMM(gMVPMatrix, 0, gProjectionMatrix, 0, gMVPMatrix, 0);

		glUniformMatrix4fv(gGridMVPMatrixHandle, 1, GL_FALSE, gMVPMatrix);

		glDrawArrays(GL_LINES, 0, 2);

		grid[6] = grid[9] = (float) i * 0.5f;
		glDrawArrays(GL_LINES, 2, 2);
	}
}

void drawcylinder(float top, float bottom, float size) {
	glUseProgram(gProgram);
	for (int i = 0; i < 146; i++) {
		cylinder[i*3] = cos((int)(i/2)*5) * size;
		cylinder[(i*3)+2] = sin((int)(i/2)*5) * size;
		if(i%2)
			cylinder[(i*3)+1] = top;
		else
			cylinder[(i*3)+1] = bottom;

		if (i < 72) {
			cylindertop[(i+1)*3] = cos(i*5) * size;
			cylindertop[(i+1)*3+1] = top;
			cylindertop[(i+1)*3+2] = cylinderbottom[(i+1)*3+2] = sin(i*5) * size;
			cylinderbottom[(i+1)*3+1] = bottom;
			cylinderbottom[(i+1)*3] = -cos(i*5) * size;
		}
	}

	cylindertop[0] = cylindertop[2] = 0;
	cylindertop[1] = top;
	cylinderbottom[0] = cylinderbottom[2] = 0;
	cylinderbottom[1] = bottom;

	glVertexAttribPointer(gPositionHandle, POSITION_DATA_SIZE, GL_FLOAT,
			GL_FALSE, 0, cylinder);
	glEnableVertexAttribArray(gPositionHandle);
	glVertexAttribPointer(gColorHandle, COLOR_DATA_SIZE, GL_FLOAT, GL_FALSE, 0,
			cylindercolors);
	glEnableVertexAttribArray(gColorHandle);
	multiplyMM(gMVPMatrix, 0, gViewMatrix, 0, gModelMatrix, 0);
	multiplyMM(gMVPMatrix, 0, gProjectionMatrix, 0, gMVPMatrix, 0);

	glUniformMatrix4fv(gMVPMatrixHandle, 1, GL_FALSE, gMVPMatrix);
	glUniform3f(gLightPosHandle, gLightPosInEyeSpace[0], gLightPosInEyeSpace[1], gLightPosInEyeSpace[2]);

	glDrawArrays(GL_TRIANGLE_STRIP, 0, 146);


	glVertexAttribPointer(gPositionHandle, POSITION_DATA_SIZE, GL_FLOAT,
			GL_FALSE, 0, cylindertop);
	glEnableVertexAttribArray(gPositionHandle);
	glVertexAttribPointer(gColorHandle, COLOR_DATA_SIZE, GL_FLOAT, GL_FALSE, 0,
			cylindercolors);
	glEnableVertexAttribArray(gColorHandle);
	glVertexAttribPointer(gNormalHandle, NORMAL_DATA_SIZE, GL_FLOAT, GL_FALSE,
			0, cylindertopnormal);
	glEnableVertexAttribArray(gNormalHandle);

	multiplyMM(gMVPMatrix, 0, gViewMatrix, 0, gModelMatrix, 0);
	multiplyMM(gMVPMatrix, 0, gProjectionMatrix, 0, gMVPMatrix, 0);

	glUniformMatrix4fv(gMVPMatrixHandle, 1, GL_FALSE, gMVPMatrix);
	glUniform3f(gLightPosHandle, gLightPosInEyeSpace[0], gLightPosInEyeSpace[1], gLightPosInEyeSpace[2]);

	glDrawArrays(GL_TRIANGLE_FAN, 0, 73);


	glVertexAttribPointer(gPositionHandle, POSITION_DATA_SIZE, GL_FLOAT,
			GL_FALSE, 0, cylinderbottom);
	glEnableVertexAttribArray(gPositionHandle);
	glVertexAttribPointer(gColorHandle, COLOR_DATA_SIZE, GL_FLOAT, GL_FALSE, 0,
			cylindercolors);
	glEnableVertexAttribArray(gColorHandle);
	glVertexAttribPointer(gNormalHandle, NORMAL_DATA_SIZE, GL_FLOAT, GL_FALSE,
			0, cylinderbottomnormal);
	glEnableVertexAttribArray(gNormalHandle);

	multiplyMM(gMVPMatrix, 0, gViewMatrix, 0, gModelMatrix, 0);
	multiplyMM(gMVPMatrix, 0, gProjectionMatrix, 0, gMVPMatrix, 0);

	glUniformMatrix4fv(gMVPMatrixHandle, 1, GL_FALSE, gMVPMatrix);
	glUniform3f(gLightPosHandle, gLightPosInEyeSpace[0], gLightPosInEyeSpace[1], gLightPosInEyeSpace[2]);

	glDrawArrays(GL_TRIANGLE_FAN, 0, 73);


}
void renderFrame() {

	glClear(GL_COLOR_BUFFER_BIT);

	setIdentityM(gLightModelMatrix, 0);
	translateM(gLightModelMatrix, 0, 0.0f, 0.0f, -5.0f);
	multiplyMV(gLightPosInWorldSpace, gLightModelMatrix, gLightPosInModelSpace);
	multiplyMV(gLightPosInEyeSpace, gViewMatrix, gLightPosInWorldSpace);

	setIdentityM(gModelMatrix, 0);
	translateM(gModelMatrix, 0, 0.0f, 0.0f, -5.0f);

	drawgrid();

	if (359.0 <= angleInDegrees) {
		angleInDegrees = 0.1;
	} else {
		angleInDegrees = angleInDegrees + 1.0;
	}

	setIdentityM(gModelMatrix, 0);
	//translateM(gModelMatrix, 0, 0.0f, 0.0f, -5.0f);
	translateM(gModelMatrix, 0, angleInDegrees*0.1f-5.0f, 0.0f, -5.0f);
	//rotateM(gModelMatrix, 0, 90, 1.0f, 1.0f, 0.0f);
	rotateM(gModelMatrix, 0, angleInDegrees*0.1f, 0.0f, 1.0f, 0.0f);

	drawCube(cubePosition, cubeColor);

	setIdentityM(gModelMatrix, 0);
	//translateM(gModelMatrix, 0, 0.0f, 1.0f, -5.0f);
	translateM(gModelMatrix, 0, angleInDegrees*0.1f-5.0f, 1.0f, -5.0f);
	//rotateM(gModelMatrix, 0, 120, 1.0f, 0.0f, 0.0f);
	rotateM(gModelMatrix, 0, angleInDegrees*0.1f, 0.0f, 1.0f, 0.0f);

	drawcylinder(1.0, 0.7, 1.0);


	setIdentityM(gModelMatrix, 0);
	//translateM(gModelMatrix, 0, 0.0f, -3.0f, -5.0f);
	translateM(gModelMatrix, 0, angleInDegrees*0.1f-5.0f, -2.0f, -5.0f);
	//rotateM(gModelMatrix, 0, 120, 1.0f, 0.0f, 0.0f);
	rotateM(gModelMatrix, 0, angleInDegrees*0.1f, 0.0f, 1.0f, 0.0f);

	drawcylinder(1.0, 0.7, 1.0);
}

extern "C" {
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_create(JNIEnv * env, jobject object);
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject object, jint width, jint height);
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject object, jfloat x, jfloat y);
}

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_create(JNIEnv * env, jobject object)
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	//glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);

	setLookAtM(gViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
	gProgram = createProgram(gVertexShader, gFragmentShader);
	gGridProgram = createProgram(gGridVertexShader, gGridFragmentShader);
}

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject object, jint width, jint height)
{
	glViewport(0, 0, width, height);
	const GLfloat ratio = (GLfloat) width / height;
	const GLfloat left = -ratio;
	const GLfloat right = ratio;
	const GLfloat bottom = -1.0f;
	const GLfloat top = 1.0f;
	const GLfloat near = 1.0f;
	const GLfloat far = 10.0f;

	frustumM(gProjectionMatrix, 0, left, right, bottom, top, near, far);

	setupGraphics();

}

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject object, jfloat x, jfloat y)
{
	static float x_old, y_old, x_accu, y_accu;
	float x_diff, y_diff;

	x_diff = x_old - x;
	y_diff = y_old - y;
	x_old = x;
	y_old = y;

	if (x_diff > 20.0f)
		x_diff = 20.0f;
	else if (x_diff < -20.0f )
		x_diff = -20.0f;

	LOGI("x = %f, y = %f",x, y);
	LOGI("x_diff = %f, y_diff = %f",x_diff, y_diff);
	//LOGI("x_accu = %f, y_accu = %f",x_accu, y_accu);
	//lookX += x_diff*0.1;
	//lookY += y_diff*0.1;
	//LOGI("x = %f, y = %f",lookX, lookY);

	setLookAtM(gViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
	renderFrame();
}
